package net.rock.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.rock.exception.ObjectMappingException;
import net.rock.mapper.UserMapper;
import net.rock.pojo.User;
import net.rock.utils.MapperUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;

import java.io.IOException;
import java.util.Date;
import java.util.Optional;

@Service
public class UserService {
    private static final ObjectMapper OM = MapperUtil.MP;
    private static final String SESSION_PREFIX = "SESSION_";
    private static final Integer EXPIRE_TIME_SEC = 3600;

    @Autowired
    UserMapper userMapper;

    @Autowired
    private JedisCluster cluster;

    public User fetchUserById(int id) {
        return userMapper.fetchUserById(id);
    }

    public User fetchUserByName(String name) {
        return userMapper.fetchUserByName(name);
    }

    public User fetchUserBySessionId(String sessionId) {
        if (StringUtils.isEmpty(sessionId)) {
            return null;
        }
        String userJson = cluster.get(SESSION_PREFIX + sessionId);

        User user = null;
        if (StringUtils.isNotEmpty(userJson)) {
            try {
                user = OM.readValue(userJson, User.class);
            } catch (IOException e) {
                throw new ObjectMappingException(e);
            }
        }
        return user;
    }

    public void register(User user) {
        userMapper.register(user);
    }

    // 返回SessionID
    public Optional<String> login(String username, String password, int permission) {
        User user = fetchUserByName(username);

        if (user == null || !password.equals(user.getPassword()) || permission > user.getPermission()) {
            return Optional.empty();
        } else {
            Date now = new Date();
            String sessionId = DigestUtils.md5Hex(username + now);
            try {
                String userJson = OM.writeValueAsString(user);
                cluster.setex(SESSION_PREFIX + sessionId, EXPIRE_TIME_SEC, userJson);
            } catch (JsonProcessingException e) {
                throw new ObjectMappingException(e);
            }
            return Optional.of(sessionId);
        }
    }

    public void logout(String sessionId) {
        cluster.del(SESSION_PREFIX + sessionId);
    }

    public void deleteUser(int id) {
        userMapper.deleteUser(id);
    }
}
